import {findNodeByCode} from './treeUtil.js'
import {isImg, replaceByObj,emptyVal} from "./xUtil.js";

/**
 *
 * cfg {data :jdMenu , style : class , }
 * }
 *
 */

const tmplBase = `<div class="{{class}}" data-key="top-menu-cntr">
                    <div data-key="top-menu-head">                  
                    </div>
                    <div data-key="top-menu-main">        
                        <div  data-key="top-menu-body">    
                        </div>
                    </div>
                 </div> `;
const tmplUl = '<ul>{{ulHtml}}</ul>';
const tmplLi = '<li>{{liHtml}}</li>';
const tmplName = '<span>{{name}}</span>';
const tmplTopMenuItem = '<a {{href}}> {{icon}} {{name}} {{badge}}</a>';
const tmplSubMenu = `<div data-key="top-menu-group">
                       {{tag}}
                       <div data-key="top-menu-sub">
                       {{subHtml}}                   
                       </div>
                   </div>`;

const tmplMenuItemCntr = '<div class="x-item" {{dataKey}} {{dataCode}}>{{item}}</div>';
const tmplMenuTagItem = '{{icon}} {{name}}';
const tmplHref = ' href="{{link}}"';
const tmplDataKey = 'data-key={{dataKey}}';
const tmplDataCode = 'data-code={{dataCode}}';
const tmplMenuBadge = '<span  class="x-badge {{type}}">{{data}}</span>';
const tmplImg = '<img src="{{icon}}"  {{dataKey}}   {{dataCode}} >';
const tmplIcon = '<i class="iconfont {{icon}}" {{dataKey}} {{dataCode}} ></i>';

export default class xTopMenu {
    /* 定义变量 开始*/
    $root;
    $main;
    $body;
    $container;
    $head;
    vJdMenu;
    vActiveItem;

    /*定义变量 结束*/

    // 构造函数
    constructor(cfg) {
        this.$root = $('#' + cfg.el);
        this.vJdMenu = cfg.data;
        this.$root.html(tmplBase.replace('{{class}}', !cfg.style ? 'top-menu-style-1' : cfg.style));
        this.init();
    };

    init() {
        this.$container = this.$root.find('[data-key="top-menu-cntr"]');
        this.$main = this.$container.find('[data-key="top-menu-main"]');
        this.$head = this.$container.find('[data-key="top-menu-head"]');
        this.$body = this.$container.find('[data-key="top-menu-body"]');
        this.renderHead();
        this.$container.on('mouseenter', '[data-key="top-menu-item"]', this.menuItemIn.bind(this));
        //注意 这里 不需要 再加选择
        this.$container.on('mouseleave', this.menuCntrOut.bind(this));
        this.$main.hide();
    }

    renderHead() {
        let [ulHtml] = ['', '', ''];
        for (let j of this.vJdMenu) {
            ulHtml += tmplLi.replace('{{liHtml}}', this.renderMenuItem(j));
        }
        this.$head.html(tmplUl.replace('{{ulHtml}}', ulHtml));
    }

    renderBody(jd) {
        let html;
        if (jd)
            if (jd["callback"])
                html = jd["callback"](jd);
            else if (jd.children)
                html = this.renderSubMenu(jd);
            else
                html = '';
        this.$body.html(html);
    }

    renderSubMenu(jd) {
        let [tag, groups, group, subItems] = ['', '', '', ''];
        for (let i = 0; i < jd.children.length; i++) {
            let o = jd.children[i];
            //存在tag 要分组 如果有上一组 就要先处理上一组
            if (o.tag) {
                //需要先处理上一组
                if (tag) {
                    //上一组处理
                    group = tmplSubMenu.replace('{{tag}}', tag);
                    group = group.replace('{{subHtml}}', tmplUl.replace('{{ulHtml}}', subItems));
                    groups += group;
                    //初始化下一组
                    [group, subItems] = ['', ''];
                }
                tag = this.renderMenuTag(o);
            } else
                subItems += this.renderMenuItem(o, 'top-menu-sub');
        }

        // 最后一组处理
        group = tmplSubMenu.replace('{{tag}}', tag);
        group = group.replace('{{subHtml}}', tmplUl.replace('{{ulHtml}}', subItems));
        groups += group;
        return groups;
    };

    menuItemIn(e) {
        let code = parseInt(e.currentTarget.getAttribute("data-code"));
        let jd = findNodeByCode(this.vJdMenu, code);
        if (jd && (jd["callback"] || jd.children)) {
            this.renderBody(findNodeByCode(this.vJdMenu, code));
            this.$main.show();
            this.setOffset(e.currentTarget.firstChild);
            if (this.vActiveItem && this.vActiveItem != $(e.currentTarget))
                this.vActiveItem.removeClass("active");
            $(e.currentTarget).addClass("active");
            this.vActiveItem = $(e.currentTarget);
        } else {
            /*本身不需要渲染的，
             因为没有 item out 事件，
             就需要清理上一个menuitem in 的痕迹*/
            this.$main.hide();
            if (this.vActiveItem)
                this.vActiveItem.removeClass("active");
        }
    }

    setOffset(target) {
        let elOffset = $(target).offset();
        let mid = elOffset.left + $(target).outerWidth(true) / 2;
        //动态渲染的，包含图片,必须指定图片大小
        let mWidth;
        mWidth = this.$main.outerWidth(true);
        let cw = document.documentElement.clientWidth || document.body.clientWidth;
        let mLeft = Math.floor(mid - mWidth / 2);
        mLeft = mLeft > 5 ? mLeft : 5;
        if (mLeft + mWidth > cw)
            mLeft = cw - mWidth - 2;
        let mTop = this.$head.offset().top + this.$head.outerHeight(true);

        // 相对 document 定位
        // top  来自 $head的高度 + outerHeight
        this.$main.css("top", mTop);
        this.$main.css("left", mLeft);

    };

    menuCntrOut(e) {
        this.$main.hide();
        if (this.vActiveItem)
            this.vActiveItem.removeClass("active");
    }

    renderMenuTag(jData) {
        let icon = '';
        if (jData.icon) {
            icon = isImg(jData.icon) ? tmplImg : tmplIcon;
            icon = replaceByObj(icon, {dataKey: '', dataCode: '', icon: jData.icon});
        }

        let name = tmplName.replace('{{name}}', jData.tag);
        let dataKey = tmplDataKey.replace('{{dataKey}}', 'menu-tag');
        let item = replaceByObj(tmplMenuTagItem,
            {name, icon});
        return replaceByObj(tmplMenuItemCntr, {item, dataCode: '', dataKey});
    }

    renderMenuItem(jData, key) {
        let [badge, active] = ['', ''];
        let href = jData.link;
        let icon = '';
        if (jData.icon) {
            icon = isImg(jData.icon) ? tmplImg : tmplIcon;
            icon = replaceByObj(icon, {dataKey: '', dataCode: '', icon: jData.icon});
        }
        if (jData.badge)
            badge = replaceByObj(tmplMenuBadge,
                {
                    type: jData.badge.split(" ")[0],
                    data: jData.badge.split(" ")[1] ? jData.badge.split(" ")[1] : ''
                })
        let name = tmplName.replace('{{name}}', emptyVal(jData.name));
        let dataKey = tmplDataKey.replace('{{dataKey}}', key ? key : 'top-menu-item');
        let dataCode = tmplDataCode.replace('{{dataCode}}', jData.code);

        href = tmplHref.replace('{{link}}', href ? href : '#');

        let item = replaceByObj(tmplTopMenuItem,
            {name, badge, icon, href});

        return replaceByObj(tmplMenuItemCntr, {item, dataCode, dataKey});
    }

}